/**
 * @brief write sample.
 *
 * @return int
 */
int tx_sample( ) {
  WNCAN_CHNMSG  txdata;
  int           fdCtrlr, fdChan1, st;
  struct fd_set writeFds;
  char          chnname[32];
  UCHAR         txChan1;
  fdCtrlr = open( CANDEVICENAME, O_RDWR, 0 );
  if ( fdCtrlr == ERROR ) {
    MG_DEBUG( "can't open\n" );
    return -1;
  }
  /* START the controller!! */
  ioctl( fdCtrlr, WNCAN_HALT, 0 );
  if ( ioctl( fdCtrlr, WNCAN_TXCHAN_GET, ( int )&txChan1 ) != OK )
    goto errexit;
  sprintf( chnname, CANDEVICENAME "/%d", txChan1 );
  fdChan1 = open( chnname, O_WRONLY, 0 );
  if ( fdChan1 == ERROR ) {
    printf( "can't open channel\n" );
    goto errexit;
  }
  /* enable the channel */
  ioctl( fdChan1, WNCAN_CHN_ENABLE, 1 );
  txdata1.id    = 0x19a;
  txdata1.extId = FALSE;

  txdata1.rtr   = FALSE;
  FD_ZERO( &writeFds );
  FD_SET( fdChan1, &writeFds );
  for ( st = 140000; st < 140256; st++ ) {
    FD_SET( fdChan1, &writeFds );
    select( fdChan1 + 1, NULL, &writeFds, NULL, NULL );
    if ( FD_ISSET( fdChan1, &writeFds ) ) {
      unsigned long data = st;
      txdata1.data[0]    = ( ( char* )&data )[0];
      txdata1.data[1]    = ( ( char* )&data )[1];
      txdata1.data[2]    = ( ( char* )&data )[2];
      txdata1.data[3]    = ( ( char* )&data )[3];
      txdata1.len        = ( st % 4 ) + 1; /* 1-4 bytes */
      write( fdChan1, ( char* )&txdata1, sizeof( txdata1 ) );
      FD_CLR( fdChan1, &writeFds );
    }
  }
  /* wait until the transmit queue is empty */
  for ( ioctl( fdChan1, FIONWRITE, ( int )&st ); st;
        ioctl( fdChan1, FIONWRITE, ( int )&st ) )
    taskDelay( 5 );
  close( fdChan1 );
  close( fdCtrlr );
  return 0;
errexit:
  close( fdCtrlr );
  return -1;
}

/**
 * @brief read sample
 *
 */
#define CANDEVICENAME "/esdpci_200_0/0"
int read_test( ) {
  WNCAN_CHNMSG    rxdata;
  WNCAN_CHNCONFIG chncfg;
  int             st, i, fdCtrlr, fdChan;
  struct fd_set   readFds;
  char            chnname[32];
  UCHAR           rxChan;
  FD_ZERO( &readFds );
  fdCtrlr = open( CANDEVICENAME, O_RDWR, 0 );
  if ( fdCtrlr == ERROR ) {
    printf( "can't open\n" );
    return -1;
  }
  /* START the controller!! */
  ioctl( fdCtrlr, WNCAN_HALT, 0 );
  if ( ioctl( fdCtrlr, WNCAN_RXCHAN_GET, ( int )&rxChan ) != OK )
    goto errexit;
  sprintf( chnname, CANDEVICENAME "/%d", rxChan );
  fdChan = open( chnname, O_RDONLY, 0 );
  if ( fdChan == ERROR ) {
    printf( "can't open channel\n" );
    goto errexit;
  }
  /* configure the channel */
  chncfg.flags         = WNCAN_CHNCFG_CHANNEL;
  chncfg.channel.id    = 0x35;
  chncfg.channel.extId = FALSE;
  chncfg.channel.len   = 0; /* ignored for read configuration */
  ioctl( fdChan, WNCAN_CHNCONFIG_SET, ( int )&chncfg );
  /* enable the channel */
  ioctl( fdChan, WNCAN_CHN_ENABLE, 1 );
  st = 0;
  do {
    FD_ZERO( &readFds );
    FD_SET( fdChan, &readFds );
    select( fdChan + 1, &readFds, NULL, NULL, NULL );
    read( fdChan, ( char* )&rxdata, sizeof( rxdata ) );
    printf( "read ID: %x len %d\nData: ", rxdata.id, rxdata.len );
    for ( i = 0; i < rxdata.len; i++ )
      printf( "%x ", rxdata.data[i] );
    printf( "\n" );
    st++;
  } while ( st < 5 );
  close( fdChan );
  close( fdCtrlr );
  return 0;
errexit:
  return -1;
}